package com.jc.cloud.sign.controller.tencent;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.google.gson.JsonObject;
import com.google.gson.JsonParser;
import com.jc.cloud.sign.bean.dto.CeateConsoleLoginUrlDTO;
import com.jc.cloud.sign.bean.dto.DescribeTemplatesDTO;
import com.jc.cloud.sign.bean.dto.EmbedWebUrlDTO;
import com.jc.cloud.sign.bean.entity.*;
import com.jc.cloud.sign.common.MsgTypeContains;
import com.jc.cloud.sign.common.R;
import com.jc.cloud.sign.common.ResultResponse;
import com.jc.cloud.sign.config.CallbackAes;
import com.jc.cloud.sign.config.tencent.TencentBaseConf;
import com.jc.cloud.sign.service.*;
import com.tencentcloudapi.common.AbstractModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import javax.annotation.Resource;
import java.nio.charset.StandardCharsets;
import java.util.HashMap;
import java.util.List;

@Api(tags = "腾讯电子签回调")
@RestController
@RequestMapping("/tencent")
@Slf4j
@Validated
public class TencentSingCallBackController {
    @Resource
    private TencentBaseConf tencentBaseConf;
    @Autowired
    private TencentSignService tencentSingService;
    //    平台企业授权电子签通知
    @Autowired
    private TbOrgNotifyService tbOrgNotifyService;
    //    二、授权书审核结果回调
    @Autowired
    private TbOrgAuditresultService tbOrgAuditresultService;
    //三. 企业开通电子签服务
    @Autowired
    private TbOrgOpensignService tbOrgOpensignService;
    //四. 员工加入企业通知
    @Autowired
    private TbOrgJoinenterpriseService tbOrgJoinenterpriseService;
    //五. 经办人授权通知
    @Autowired
    private TbOrgAuthorizationmanagerService tbOrgAuthorizationmanagerService;
    //六. 超管变更通知
    @Autowired
    private TbOrgOverpipechangeService tbOrgOverpipechangeService;
    // 七. 员工变更角色通知
    @Autowired
    private TbOrgRolechangeService tbOrgRolechangeService;
    //八. 企业基础信息修改通知  关联表
    @Autowired
    private TbOrgBasicinfomodifyService tbOrgBasicinfomodifyService;
    @Autowired
    private TbOrgOrganizationchangebaseinfodetailService tbOrgOrganizationchangebaseinfodetailService;
    //九. 企业注销通知
    @Autowired
    private TbOrgBusinesscancellationService tbOrgBusinesscancellationService;
    //十. 企业收录申请审核结果回调
    @Autowired
    private TbOrgReviewresultscallbackService tbOrgReviewresultscallbackService;
    //    一. 模板新增通知
    @Autowired
    private TbOrgTemplateadditionService tbOrgTemplateadditionService;
    //    二. 模板修改通知
    @Autowired
    private TbOrgTemplatemodificationService tbOrgTemplatemodificationService;
    //    三. 模板删除通知
    @Autowired
    private TbOrgTemplatedeletionService tbOrgTemplatedeletionService;
    @Resource
    private TbOrgStamprelatedService tbOrgStamprelatedService;
    @Resource
    private TbOrgSealauditresultService tbOrgSealauditresultService;
    @Resource
    private TbTransfersigntaskService tbTransfersigntaskService;
    @Resource
    private TbContractdeductionNotifyService tbContractdeductionNotifyservice;
    @Resource
    private TbContractreviewNotifyService tbContractreviewNotifyService;
    @Resource
    private TbContractstatuschangeNotifyService tbContractstatuschangeNotifyService;
    @Resource
    private TbContractstatuschangeNotifyCcinfoService tbContractstatuschangeNotifyCcinfoService;
    @Resource
    private TbContractstatuschangeNotifyFlowapproverinfoService tbContractstatuschangeNotifyFlowapproverinfoService;
    @Resource
    private TbContractstatuschangeNotifyFlowgroupmessageService tbContractstatuschangeNotifyFlowgroupmessageService;
    @Resource
    private TbContractstatuschangeNotifyFlowgroupmessageFlowsinfoService tbContractstatuschangeNotifyFlowgroupmessageFlowsinfoService;
    @Resource
    private TbContractcancelService tbContractcancelService;
    @Resource
    private TbOrgauthorizesdownloadNotifyService tbOrgauthorizesdownloadNotifyService;
    @Resource
    private TbOrgcancellationauthorizationNotifyService tbOrgcancellationauthorizationNotifyService;
    @Resource
    private TbDocumentsynthesizedNotifyService tbDocumentsynthesizedNotifyService;
    @Resource
    private TbSigncontractfailureNotifyService tbSigncontractfailureNotifyService;
    @Resource
    private TbSilentsignNotifyService tbSilentsignNotifyService;

    /**
     * @Author HongQiYi
     * @Description // 所有的回调入库都在这里实现
     **/
    @ApiOperation("回调地址验证")
    @PostMapping("/signCallback")
    @ApiImplicitParam(name = "callBackMsg", value = "回调消息", required = false, dataType = "string", paramType = "query")
    @ResponseBody
    @Transactional
    public ResultResponse signCallback(@RequestBody String callbackstruct) throws Exception {
        //对回调的数据进行解密
        //将解密之后的数据进行解析
        log.error("callBackMsg:" + callbackstruct);
//        return ResultResponse.success();
        // 传入CallbackUrlKey

//        解析JSON字符串
        JsonObject jsonObject = JsonParser.parseString(callbackstruct).getAsJsonObject();
        // 获取指定键的值
        String encryptedValue = jsonObject.get("encrypt").getAsString();

        byte[] key = tencentBaseConf.getCallbackUrlKey().getBytes();

        // 传入密文
        byte[] origData = CallbackAes.aesDecrypt(encryptedValue.getBytes(StandardCharsets.UTF_8), key);

        String msg = new String(origData, StandardCharsets.UTF_8);
        //转换为json对象
        JSONObject msgJsonObject = JSONObject.parseObject(msg);
        //取里面的键值对
        String msgType = msgJsonObject.getString("MsgType");
        JSONObject msgDataJsonObject = msgJsonObject.getJSONObject("MsgData");

        switch (msgType) {
            // 1.平台企业授权电子签通知
            case MsgTypeContains.OrgAuth:
                TbOrgNotifyEntity tbOrgNotify =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgNotifyEntity.class); //json对象转换为TborgNotify对象
                tbOrgNotifyService.save(tbOrgNotify);
                break;

            // 2.授权书审核结果
            case MsgTypeContains.OrgCertify:
                TbOrgAuditresultEntity tbOrgAuditresult =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgAuditresultEntity.class);
                tbOrgAuditresultService.save(tbOrgAuditresult);
                break;

            // 三. 企业开通电子签服务
            case MsgTypeContains.OrgOpenTsignBiz:
                TbOrgOpensignEntity tbOrgOpensign =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgOpensignEntity.class);
                tbOrgOpensignService.save(tbOrgOpensign);
                break;

            //四. 员工加入企业通知 tbOrgJoinenterpriseService
            case MsgTypeContains.VerifyStaffInfo:
                TbOrgJoinenterpriseEntity tbOrgJoinenterprise =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgJoinenterpriseEntity.class);
                tbOrgJoinenterpriseService.save(tbOrgJoinenterprise);
                break;

            //五. 经办人授权通知  tbOrgAuthorizationmanagerService
            case MsgTypeContains.OperatorAuth:
                TbOrgAuthorizationmanagerEntity tbOrgAuthorizationmanager =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgAuthorizationmanagerEntity.class);
                tbOrgAuthorizationmanagerService.save(tbOrgAuthorizationmanager);
                break;

            //六. 超管变更通知 tbOrgOverpipechangeService
            case MsgTypeContains.SuperAdminChange:
                TbOrgOverpipechangeEntity tbOrgOverpipechange =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgOverpipechangeEntity.class);
                tbOrgOverpipechangeService.save(tbOrgOverpipechange);
                break;

            //七. 员工变更角色通知 tbOrgRolechangeService
            case MsgTypeContains.RolesChange:
                TbOrgRolechangeEntity tbOrgRolechange =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgRolechangeEntity.class);
                tbOrgRolechangeService.save(tbOrgRolechange);
                break;

            //八. 企业基础信息修改通知 TODO  关联表 tbOrgBasicinfomodifyService
            case MsgTypeContains.ModifyOrganizationBaseInfo:
                JSONObject organizationChangeBaseInfo = msgDataJsonObject.getJSONObject("OrganizationChangeBaseInfo");
                TbOrgBasicinfomodifyEntity tbOrgBasicinfomodify =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgBasicinfomodifyEntity.class);
                tbOrgBasicinfomodifyService.save(tbOrgBasicinfomodify);

                if(organizationChangeBaseInfo!=null&&organizationChangeBaseInfo.size()>0){
                    Long id = tbOrgBasicinfomodify.getId();
                    //取json对象里边的json对象
//                JSONObject organizationChangeBaseInfo = msgDataJsonObject.getJSONObject("OrganizationChangeBaseInfo");
                    TbOrgOrganizationchangebaseinfodetailEntity tbOrgOrganizationchangebaseinfodetail =JSONObject.parseObject(organizationChangeBaseInfo.toJSONString(), TbOrgOrganizationchangebaseinfodetailEntity.class);
                    tbOrgOrganizationchangebaseinfodetail.setTbOrgBasicinfomodifyid(id);
                    tbOrgOrganizationchangebaseinfodetailService.save(tbOrgOrganizationchangebaseinfodetail);
                }

                break;

            //九. 企业注销通知  tbOrgBusinesscancellationService
            case MsgTypeContains.CloseOrganization:
                TbOrgBusinesscancellationEntity tbOrgBusinesscancellation =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgBusinesscancellationEntity.class);
                tbOrgBusinesscancellationService.save(tbOrgBusinesscancellation);
                break;

            //十. 企业收录申请审核结果回调  tbOrgReviewresultscallbackService
            case MsgTypeContains.OrgAuthAudit:
                TbOrgReviewresultscallbackEntity tbOrgReviewresultscallback =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgReviewresultscallbackEntity.class);
                tbOrgReviewresultscallbackService.save(tbOrgReviewresultscallback);
                break;

            //一. 模板新增通知  tbOrgTemplateadditionService
            case MsgTypeContains.TemplateAdd:
                TbOrgTemplateadditionEntity tbOrgTemplateaddition =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgTemplateadditionEntity.class);
                tbOrgTemplateadditionService.save(tbOrgTemplateaddition);
                break;

            //二. 模板修改通知  tbOrgTemplatemodificationService
            case MsgTypeContains.TemplateUpdate:
                TbOrgTemplatemodificationEntity tbOrgTemplatemodification =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgTemplatemodificationEntity.class);
                tbOrgTemplatemodificationService.save(tbOrgTemplatemodification);
                break;

            //三. 模板删除通知  tbOrgTemplatedeletionService
            case MsgTypeContains.TemplateDelete:
                TbOrgTemplatedeletionEntity tbOrgTemplatedeletion =JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgTemplatedeletionEntity.class);
                tbOrgTemplatedeletionService.save(tbOrgTemplatedeletion);
                break;
            //印章创建、删除、停用、启用、授权/解除授权回调
            case MsgTypeContains.OperateSeal:
                TbOrgStamprelatedEntity tbOrgStamprelated = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgStamprelatedEntity.class);
                tbOrgStamprelatedService.save(tbOrgStamprelated);
                break;
            //印章审核结果通知
            case MsgTypeContains.AuditSealAuth:
                TbOrgSealauditresultEntity tbOrgSealauditresult = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgSealauditresultEntity.class);
                tbOrgSealauditresultService.save(tbOrgSealauditresult);
                break;
            //转交签署任务
            case MsgTypeContains.ForwardFLow:
                TbTransfersigntaskEntity tbTransfersigntask = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbTransfersigntaskEntity.class);
                tbTransfersigntaskService.save(tbTransfersigntask);
                break;
            //合同发起扣费通知
            case MsgTypeContains.FlowCost1:
                TbContractdeductionNotifyEntity tbContractdeductionNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbContractdeductionNotifyEntity.class);
                tbContractdeductionNotifyservice.save(tbContractdeductionNotify);
                break;
            //合同撤销扣费返还通知
            case MsgTypeContains.FlowCost2:
                TbContractcancelEntity tbContractcancel = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbContractcancelEntity.class);
                tbContractcancelService.save(tbContractcancel);
                break;
            //合同审核通知
            case MsgTypeContains.CreateFlowReview:
                TbContractreviewNotifyEntity tbContractreviewNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbContractreviewNotifyEntity.class);
                tbContractreviewNotifyService.save(tbContractreviewNotify);
                break;
            //合同状态变动通知
            case MsgTypeContains.FlowStatusChange:
                JSONArray ccInfoData = msgDataJsonObject.getJSONArray("CcInfo");
                JSONArray flowApproverInfo = msgDataJsonObject.getJSONArray("FlowApproverInfo");
                JSONObject flowGroupMessage = msgDataJsonObject.getJSONObject("FlowGroupMessage");
                JSONArray flowsInfo = flowGroupMessage.getJSONArray("FlowsInfo");
                try {
                    TbContractstatuschangeNotifyEntity tbContractstatuschangeNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbContractstatuschangeNotifyEntity.class);
                    tbContractstatuschangeNotifyService.save(tbContractstatuschangeNotify);
                    if (!ccInfoData.isEmpty() && ccInfoData.size() > 0) {
                        List<TbContractstatuschangeNotifyCcinfoEntity> ccinfoList = JSONArray.parseArray(ccInfoData.toJSONString(), TbContractstatuschangeNotifyCcinfoEntity.class);
                        for (TbContractstatuschangeNotifyCcinfoEntity notifyCcinfo : ccinfoList) {
                            notifyCcinfo.setTbContractstatuschangeNotifyId(tbContractstatuschangeNotify.getId());
                            tbContractstatuschangeNotifyCcinfoService.save(notifyCcinfo);
                        }

                    }
                    if (!flowApproverInfo.isEmpty() && flowApproverInfo.size() > 0) {
                        List<TbContractstatuschangeNotifyFlowapproverinfoEntity> flowapproverinfoList = JSONArray.parseArray(flowApproverInfo.toJSONString(), TbContractstatuschangeNotifyFlowapproverinfoEntity.class);
                        for (TbContractstatuschangeNotifyFlowapproverinfoEntity notifyFlowapproverinfo : flowapproverinfoList) {
//                            notifyFlowapproverinfo.setTbContractstatuschangeNotifyId(tbContractstatuschangeNotify.getId());
                            notifyFlowapproverinfo.setTbContractstatuschangeNotifyId(tbContractstatuschangeNotify.getId());
                            tbContractstatuschangeNotifyFlowapproverinfoService.save(notifyFlowapproverinfo);
                        }
                    }
                    if (!flowGroupMessage.isEmpty() && flowGroupMessage.size() > 0) {
                        TbContractstatuschangeNotifyFlowgroupmessageEntity flowgroupmessage = JSONObject.parseObject(flowGroupMessage.toJSONString(), TbContractstatuschangeNotifyFlowgroupmessageEntity.class);
                        flowgroupmessage.setTbContractstatuschangeNotifyId(tbContractstatuschangeNotify.getId());
                        tbContractstatuschangeNotifyFlowgroupmessageService.save(flowgroupmessage);
                        if (!flowsInfo.isEmpty() && flowsInfo.size() > 0) {
                            List<TbContractstatuschangeNotifyFlowgroupmessageFlowsinfoEntity> flowgroupmessageFlowsinfoList = JSONArray.parseArray(flowsInfo.toJSONString(), TbContractstatuschangeNotifyFlowgroupmessageFlowsinfoEntity.class);
                            for (TbContractstatuschangeNotifyFlowgroupmessageFlowsinfoEntity flowgroupmessageFlowsinfo : flowgroupmessageFlowsinfoList) {
                                flowgroupmessageFlowsinfo.setTbContractstatuschangeNotifyFlowgroupmessageId(flowgroupmessage.getId());
                                tbContractstatuschangeNotifyFlowgroupmessageFlowsinfoService.save(flowgroupmessageFlowsinfo);
                            }
                        }
                    }
                    break;
                } catch (Exception e) {
                    e.printStackTrace();
                }
                //合作企业授权下载合同通知
            case MsgTypeContains.DownloadOpenAuth:
                TbOrgauthorizesdownloadNotifyEntity tbOrgauthorizesdownloadNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgauthorizesdownloadNotifyEntity.class);
                tbOrgauthorizesdownloadNotifyService.save(tbOrgauthorizesdownloadNotify);
                break;
            //合作企业取消授权下载合同通知
            case MsgTypeContains.DownloadCloseAuth:
                TbOrgcancellationauthorizationNotifyEntity tbOrgcancellationauthorizationNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgcancellationauthorizationNotifyEntity.class);
                tbOrgcancellationauthorizationNotifyService.save(tbOrgcancellationauthorizationNotify);
                break;
            //合作企业取消授权下载合同通知
            case MsgTypeContains.DocumentFill:
                TbDocumentsynthesizedNotifyEntity tbDocumentsynthesizedNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbDocumentsynthesizedNotifyEntity.class);
                tbDocumentsynthesizedNotifyService.save(tbDocumentsynthesizedNotify);
                break;
            //签署二维码发起合同失败通知
            case MsgTypeContains.CreateFlowByQrCode:
                TbSigncontractfailureNotifyEntity tbSigncontractfailureNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbSigncontractfailureNotifyEntity.class);
                tbSigncontractfailureNotifyService.save(tbSigncontractfailureNotify);
                break;
            //他方静默签授权通知
            case MsgTypeContains.PartnerServerSignAuthorization:
                TbSilentsignNotifyEntity tbSilentsignNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbSilentsignNotifyEntity.class);
                tbSilentsignNotifyService.save(tbSilentsignNotify);
                break;
        }
        return ResultResponse.success(callbackstruct);

    }

    /**
     * @Author wei
     * @Description // 生成子客登录连接
     **/
    @ApiOperation("生成子客登录链接")
    @PostMapping("/ceateConsoleLoginUrl")
    @ResponseBody
    public ResultResponse ceateConsoleLoginUrl(@Validated @RequestBody @ApiParam("传入对象") CeateConsoleLoginUrlDTO vo) {
        AbstractModel abstractModel = tencentSingService.createConsoleLoginUrl(vo);
        return ResultResponse.success(abstractModel);
    }


    /**
     * @Author wei
     * @Description // 查询模板信息列表
     **/
    @ApiOperation("查询模板信息列表")
    @PostMapping("/getDescribeFlowTemplates")
    @ResponseBody
    public R getDescribeFlowTemplates(@Validated @RequestBody @ApiParam("传入对象") DescribeTemplatesDTO vo) {
        HashMap<Object, Object> abstractModel = tencentSingService.getDescribeFlowTemplates(vo);
        return R.ok().put("data",abstractModel);
    }

    /**
     * @Author wei
     * @Description // 嵌入web链接
     **/
    @ApiOperation("嵌入web链接")
    @PostMapping("/getEmbedWebUrl")
    @ResponseBody
    public R getEmbedWebUrl(@Validated @RequestBody @ApiParam("传入对象") EmbedWebUrlDTO vo) {
        AbstractModel abstractModel = tencentSingService.getEmbedWebUrl(vo);
        return R.ok().put("data",abstractModel);
    }

    /**
     * @Author HongQiYi
     * @Description // 解密
     **/
    @ApiOperation("解密")
    @GetMapping("/decode")
    public ResultResponse getDecode() throws Exception {
        // 传入CallbackUrlKey
        byte[] key = "59D740673B7B43F98B4953EE60388797".getBytes();
        // 传入密文
        byte[] origData = CallbackAes.aesDecrypt(("{\"encrypt\":\"rUsQG/eVSRjko9pTyjzLsuqazkbY+j+QzFrVSxM4vPP4FAWdXLavZlxIYyfbf09QImPfVR2/CF6BswzVha+OYgSb8K30urXBtXtvel/sJJ1BIt3MDiwbsZPkF2T6z/OD5k4jalpeMaaPqwGMvJCOdEJozRLTQ2+t0/lAVG9keby5A41sw1gSIOFQdQqZ+jbZPXK2ygXL6VtTmEHGsGTd0XpyTW7TI6lZrcG+oTRkBHZ0ieddox/8vAmDlgaExX+MqI6Qy99BGeOdqA5fmM+0C3uwDPpdwTyb+tYw89lvft5zOJoj1nJBv0/f2L0zAbkpksHe+cQzNEydB4hcWDCVZnXdBbiW9AfkiVmOA8/y6jqw+Wlfigyg2ShnwcygQLhjBHagUH6UZkgssNh4mv0KtzqMLZQQl+gjDNcGr73KNgI+zDQH6vUW/Tw2VjcvHzt5YbbO3cqIaxidh7oUMQFoaHDb8/apOH6H75Nc+JjwAwKpyXRUrDE1iOymW7dfL0nyktua1SwCwwKshkDcg+s+po9OAwhTzDfZ8MPY7iW").getBytes(StandardCharsets.UTF_8), key);
        // 打印解密后的内容，格式为json
        String msg = new String(origData, StandardCharsets.UTF_8);
        JSONObject msgJsonObject = JSONObject.parseObject(msg);
        String msgType = msgJsonObject.getString("MsgType");
        JSONObject msgDataJsonObject = msgJsonObject.getJSONObject("MsgData");
        switch (msgType) {
            case MsgTypeContains.OrgAuth:
                TbOrgNotifyEntity tbOrgNotify = JSONObject.parseObject(msgDataJsonObject.toJSONString(), TbOrgNotifyEntity.class);
                tbOrgNotifyService.save(tbOrgNotify);
                break;
        }

        return ResultResponse.success(new String(origData, StandardCharsets.UTF_8));

    }

}
